import { activeNodeId } from '@/components/business/BaseNode/state';
import { NODE_TYPE } from '@/constants/config';
import { TVariables, findParentVariables, findVariables } from '@/utils/graph';
import { Cell } from '@antv/x6';
import { useGraph } from './useGraph';
import { ACTION_TYPE } from '@/components/business/NodeAutomaticForm/components/AutomaticForm/data';
import { DATA_LOAD_TYPE } from '@/components/business/Nodes/DataLoad/components/DataSet/data';
import { IDataLoad } from '@/components/business/Nodes/DataLoad/type';

// 1.当前私有变量 ref
// 2.当前私有node变量 ref
// 3.当前及父级私有变量 computed
// 4.当前及父级node变量 computed
// 5.当前及父级私有变量 options computed
// 6.当前及父级node变量 options computed

/** 当前私有变量 ref */
const currentPrivateVariables = ref<TVariables[]>([]);
/** 当前私有node变量 ref */
const currentNodeVariables = ref<TVariables[]>([]);
/** 当前node data ref */
const currentNodeData = ref<any>({});

export const useCurrentNode = () => {
  const { graph, saveGraph } = useGraph();

  const variablesToOptions = (variables: any[], type: string) => {
    return variables.map((item: any) => {
      return {
        label: item.varLabel!,
        value: item.varName!,
        varType: item.varType!,
        type
      };
    });
  };
  // 当前及父级私有变量 computed
  const currentAndParentPrivateVariables = computed(() => {
    const parentList = findParentVariables(graph.value!, activeNodeId.value!, 'private');
    return currentPrivateVariables.value.concat(parentList);
  });
  // 当前及父级私有变量 options computed
  const currentAndParentPrivateVariablesOptions = computed(() => {
    return variablesToOptions(currentAndParentPrivateVariables.value, 'private');
  });
  // 当前及父级node变量 computed
  const currentAndParentNodeVariables = computed(() => {
    const parentList = findParentVariables(graph.value!, activeNodeId.value!, 'node');
    return currentNodeVariables.value.concat(parentList);
  });
  // 当前及父级node变量 options computed
  const currentAndParentNodeVariablesOptions = computed(() => {
    return variablesToOptions(currentAndParentNodeVariables.value, 'private');
  });

  const getGraphNode = () => {
    if (!graph.value) return null;
    if (!activeNodeId.value) return null;
    return graph.value?.getCellById(activeNodeId.value) || null;
  };

  const getNodeData = () => {
    return getGraphNode()?.getData() || null;
  };

  const getCondition = () => {
    return (getNodeData()?.condition as any[]) || null;
  };

  const saveCondition = (condition: any) => {
    Object.assign(currentNodeData.value, { condition });
    return setData({
      condition
    });
  };

  const getConditionSetConfig = () => {
    return (getNodeData()?.conditionSetConfig as any) || null;
  };

  const saveConditionSetConfig = (conditionSetConfig: any) => {
    Object.assign(currentNodeData.value, { conditionSetConfig });
    return setData({
      conditionSetConfig
    });
  };

  const getAutomaticData = () => {
    const autoData = getNodeData()?.autoData || null;
    return autoData;
  };

  const saveAutomaticData = (autoData: any) => {
    // if (autoData && autoData.cfgType === ACTION_TYPE.INSERT) {
    //     delete autoData.conditions;
    // }
    Object.assign(currentNodeData.value, { autoData });
    return setData({
      autoData
    });
  };

  const getDataLoad = () => {
    const autoData = getNodeData()?.dataLoad || null;
    return autoData;
  };

  const saveDataLoad = (dataLoad: IDataLoad) => {
    if (dataLoad && dataLoad.cfgType === DATA_LOAD_TYPE.CHOOSE && Object.hasOwn(dataLoad, 'dataSet')) {
        delete dataLoad.dataSet;
    }
    Object.assign(currentNodeData.value, { dataLoad });
    return setData({
      dataLoad
    });
  };

  const getFeatureData = () => {
    const featureData = getNodeData()?.featureData || null;
    return featureData;
  };

  const saveFeatureData = (featureData: any) => {
    Object.assign(currentNodeData.value, { featureData });
    return setData({
      featureData
    });
  };

  const getNodeType = () => {
    return getGraphNode()?.shape as keyof typeof NODE_TYPE;
  };

  const saveCurrentPrivateVariables = (variables: any[]) => {
    const originData = getNodeData();
    currentPrivateVariables.value = [...variables];
    setData({
      ...originData,
      variables: (currentNodeData.value.variables = [...variables])
    });

    saveGraph();
  };

  const saveCurrentPrivateNodeVariables = (variables: TVariables[]) => {
    const node = getGraphNode();
    if (node) {
      const originData = getNodeData();
      if (variables.length === 0) {
        // 如果 variables 为空，则清理 originData 中的 nodeVariables
        originData.nodeVariables = [];
        currentNodeVariables.value = [];
        currentNodeData.value.nodeVariables = [];
      } else {
        originData.nodeVariables = currentNodeData.value.nodeVariables = [...variables];
        currentNodeVariables.value = [...variables];
      }
      setData({
        ...originData
      });

      saveGraph();
    }
  };

  const savePayload = (payload: string[]) => {
    const originData = getNodeData();
    setData({
      ...originData,
      payload: (currentNodeData.value.payload = {...payload})
    });

    saveGraph();
  };
  // @ts-ignore
  const setData: Cell['setData'] = (data, options) => {
    const cell = getGraphNode()?.updateData(data, options);
    Object.assign(currentNodeData.value, data);
    saveGraph();
    return cell;
  };

  watch(
    activeNodeId,
    () => {
      if (activeNodeId.value && graph.value) {
        currentPrivateVariables.value = findVariables(graph.value!, activeNodeId.value, 'private');
        currentNodeVariables.value = findVariables(graph.value!, activeNodeId.value, 'node');
      }
    },
    { immediate: true }
  );

  return {
    currentNodeData,
    currentPrivateVariables,
    currentNodeVariables,
    currentAndParentPrivateVariables,
    currentAndParentPrivateVariablesOptions,
    currentAndParentNodeVariables,
    currentAndParentNodeVariablesOptions,
    /** 设置节点数据 */
    setData,
    /** 保持图表 */
    saveGraph,
    /** 保存私有变量 */
    saveCurrentPrivateVariables,
    /** 保存节点变量 */
    saveCurrentPrivateNodeVariables,
    /** 获取当前活动节点的图形对象 */
    getGraphNode,
    /** 获取当前节点类型 */
    getNodeType,
    /** 保存条件 */
    saveCondition,
    /** 获取条件 */
    getCondition,
    /** 保存条件配置 */
    saveConditionSetConfig,
    /** 获取条件配置 */
    getConditionSetConfig,
    /** 保存自动节点 */
    saveAutomaticData,
    /** 获取自动节点 */
    getAutomaticData,
    /** 保存特征节点 */
    saveFeatureData,
    /** 获取自动节点 */
    getFeatureData,
    /** 保存数据加载节点 */
    saveDataLoad,
    /** 获取数据加载节点 */
    getDataLoad,
   /** 获取当前活动节点的数据 */
    getNodeData,
   /** 保存当前节点穿透字段，payload */
    savePayload
  };
};
